/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package toolz;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.jfree.data.xy.XYDataItem;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

import ucar.ma2.Array;
import ucar.ma2.IndexIterator;
import ucar.nc2.Attribute;
import ucar.nc2.NetcdfFile;
import ucar.nc2.Variable;

/**
 *
 * @author Bunkowski
 */ 
public class netCdfTools {


    public static XYSeriesCollection getXYSeriesCollection(double maxRt,String filename,double rtFactor,double A,double B, double C) {
        Vector<Serializable> wrap = netCdfTools.readFile(filename);
        return addSeries(maxRt,(String) wrap.get(0), (Vector<Double>) wrap.get(1), (Vector<Double>) wrap.get(2),rtFactor,A,B,C);
    }

    public static XYSeriesCollection addSeries(double maxRt,String name, Vector<Double> dataLine, Vector<Double> numericXAchsis,double rtFactor,double A,double B, double C) {
        XYSeriesCollection lineDataset = new XYSeriesCollection();
        XYSeries series = new XYSeries(name);
        for (int j = 0; j < dataLine.size(); j++) {
            Double d = dataLine.get(j);
            series.add(numericXAchsis.get(j), d);
        }
        lineDataset.addSeries(series);        
        return toMCCDatasetYX(maxRt,lineDataset,rtFactor,A,B,C);
    }

    public static XYSeriesCollection toMCCDataset(XYSeriesCollection lineDataset,double A,double B, double C){
        XYSeriesCollection newSC = new XYSeriesCollection();
        for (int i = 0; i < lineDataset.getSeriesCount(); i++) {
            XYSeries series = lineDataset.getSeries(i);
            XYSeries newSeries = new XYSeries(series.getKey());
            for (int j = 0; j < series.getItemCount(); j++) {
                XYDataItem item = series.getDataItem(j);
                double x = item.getXValue();
                double y = item.getYValue();
                if (netCdfTools.GcToMcc(x,A,B,C)>500) break;
                newSeries.add(netCdfTools.GcToMcc(x,A,B,C), y);
            }
            newSC.addSeries(newSeries);
        }
        lineDataset.removeAllSeries();
        for (Object o : newSC.getSeries()) {
            XYSeries series = (XYSeries)o;
            lineDataset.addSeries(series);
        }
        return newSC;
    }

        public static XYSeriesCollection toMCCDatasetYX(double maxRt,XYSeriesCollection lineDataset,double rtFactor,double A,double B, double C){
        XYSeriesCollection newSC = new XYSeriesCollection();
        for (int i = 0; i < lineDataset.getSeriesCount(); i++) {
            XYSeries series = lineDataset.getSeries(i);
            XYSeries newSeries = new XYSeries(series.getKey(),false,true);
            for (int j = 0; j < series.getItemCount(); j++) {
                XYDataItem item = series.getDataItem(j);
                double x = item.getXValue();
                double y = item.getYValue();
                if (netCdfTools.GcToMcc(x,A,B,C)>maxRt) break;
                newSeries.add(y,netCdfTools.GcToMcc(x,A,B,C)*rtFactor);
            }

            newSC.addSeries(newSeries);
        }
        lineDataset.removeAllSeries();
        for (Object o : newSC.getSeries()) {
            XYSeries series = (XYSeries)o;
            lineDataset.addSeries(series);
        }
        return newSC;
    }
                  
            
        

    public static Vector<Serializable> readFile(String filename){
                NetcdfFile ncfile = null;
                Vector<Double> tic = null;
                Vector<Double> ticChartAxis = null;
                String administrativeComments = "";
                String experimentTitle = "";
                try {
                    ncfile = NetcdfFile.open(filename);
                    for (Attribute a :ncfile.getGlobalAttributes()){
                        System.out.println(a.toString());
                    }


                    experimentTitle = ncfile.findGlobalAttribute("experiment_title").getStringValue();
                    administrativeComments = ncfile.findGlobalAttribute("administrative_comments").getStringValue();


                    for (Variable v : ncfile.getVariables()) {
                        System.out.println(v.toString());
                    }
                    tic = netCdfTools.getVector("total_intensity", ncfile);
                    ticChartAxis = netCdfTools.getVector("scan_acquisition_time", ncfile);

                    for (int i = 0; i < ticChartAxis.size(); i++) {
                        ticChartAxis.set(i,ticChartAxis.elementAt(i)/60);
                    }
                } catch (IOException ioe) {
                    System.out.println("trying to open " + filename);
                } finally {
                    if (null != ncfile) {
                        try {
                            ncfile.close();
                        } catch (IOException ioe) {
                            System.out.println("trying to close " + filename);
                        }
                    }
                }
                Vector<Serializable> wrap = new Vector<Serializable>();
                wrap.add(new File(filename).getName()+" "+administrativeComments+"/"+experimentTitle);
                wrap.add(tic);
                wrap.add(ticChartAxis);
                wrap.add(filename);
                return wrap;
    }



    public static Vector<Double> getVector(String name, NetcdfFile ncfile) {
        Vector<Double> v = new Vector<Double>();
        try {
            Array read = ncfile.findVariable(name).read();
            IndexIterator ii = read.getIndexIterator();
            while (ii.hasNext()) {
                v.add(ii.getDoubleNext());
            }
        } catch (IOException ex) {
            Logger.getLogger(netCdfTools.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v;
    }
    


    public static double MccToGc(double mcc){
        double A = 7.92065;
        double B = 2.60168;
        double C = -2.58105;

        double gc = A+B*Math.log(mcc+C);
        return gc;
    }

    public static double GcToMcc(double gc,double A,double B, double C){
//        double A = 7.92065;
//        double B = 2.60168;
//        double C = -2.58105;
        double mcc = Math.expm1((gc-A)/B)-C;
        return mcc;
        
        
    }

}
